import 'package:connectivity/connectivity.dart';
import 'package:dio/dio.dart';
import 'result.dart';

enum Method { GET, POST, DELETE, PUT, PATCH, HEAD }
//使用：MethodValues[Method.POST]
const MethodValues = {
  Method.GET: "get",
  Method.POST: "post",
  Method.DELETE: "delete",
  Method.PUT: "put",
  Method.PATCH: "patch",
  Method.HEAD: "head",
};

class BaseRequest {
  Dio _dio;
  void setDio(Dio dio) {
    this._dio = dio;
  }
  Future<Result<T>> get<T>(String path,{Map<String, dynamic> params = const {},bool withToken= false,bool showMsg = true}){
    return _request(Method.GET, path,params: params,withToken: withToken,showMsg: showMsg);
  }

  Future<Result<T>> post<T>(String path,{dynamic params,bool withToken= false,bool showMsg = true}){
    return _request(Method.POST, path,data: params,withToken: withToken,showMsg: showMsg);
  }

  Future<Result<T>> _request<T>(Method method,String path,{dynamic data,Map<String, dynamic> params,bool withToken,bool showMsg}) async{
    try {
      ConnectivityResult netResult =  await Connectivity().checkConnectivity();
      if(netResult == ConnectivityResult.none){
        throw DioError(error: '网络未连接',type: DioErrorType.other,requestOptions: RequestOptions(path: path));
      }
      
      if(withToken){
        _dio.options.headers = {
          'token':'E6FCA68031822A0626C200B10F2F5F5D'
        };
      }else{
        _dio.options.headers.remove('token');
      }


      Response response = await _dio.request(path,data:data,queryParameters: params, options: Options(method: MethodValues[method]));
      return Result<T>(code: 0,data: response.data,message: '成功',showMsg: showMsg)..fixModel();
    } on DioError catch(error) {
      return createErrorRespond(error,showMsg);
    }
  }
  // 错误信息
  Result<T> createErrorRespond<T>(DioError error,bool showMsg) {
    switch (error.type) {
      case DioErrorType.cancel:{
        return Result<T>(message: '请求取消',showMsg: showMsg);
      }
      break;
      case DioErrorType.connectTimeout:{
        return Result<T>(message: '连接超时',showMsg: showMsg);
      }
      break;
      case DioErrorType.sendTimeout:{
        return Result<T>(message: '请求超时',showMsg: showMsg);
      }
      break;
      case DioErrorType.receiveTimeout:{
        return Result<T>(message: '响应超时',showMsg: showMsg);
      }
      break;
      case DioErrorType.response:{
        try {
          int errCode = -1;
          if(error != null){
            errCode = error.response.statusCode;
          }
          return Result<T>(message: '错误代码：' + errCode.toString(),showMsg: showMsg);
//          switch (errCode) {
//            case 400: {
//              return ErrorEntity(code: errCode, message: "请求语法错误",showMsg: showMsg);
//            }
//            break;
//            case 403: {
//              return ErrorEntity(code: errCode, message: "服务器拒绝执行",showMsg: showMsg);
//            }
//            break;
//            case 404: {
//              return ErrorEntity(code: errCode, message: "无法连接服务器",showMsg: showMsg);
//            }
//            break;
//            case 405: {
//              return ErrorEntity(code: errCode, message: "请求方法被禁止",showMsg: showMsg);
//            }
//            break;
//            case 500: {
//              return ErrorEntity(code: errCode, message: "服务器内部错误",showMsg: showMsg);
//            }
//            break;
//            case 502: {
//              return ErrorEntity(code: errCode, message: "无效的请求",showMsg: showMsg);
//            }
//            break;
//            case 503: {
//              return ErrorEntity(code: errCode, message: "服务器挂了",showMsg: showMsg);
//            }
//            break;
//            case 505: {
//              return ErrorEntity(code: errCode, message: "不支持HTTP协议请求",showMsg: showMsg);
//            }
//            break;
//            default: {
//              return ErrorEntity(code: errCode, message: "未知错误",showMsg: showMsg);
//            }
//          }
        } on Exception catch(_) {
          return Result<T>(message: '数据异常，请稍后再试',showMsg: showMsg);
        }
      }
      break;
      default: {
        return Result<T>(message: error.message,);
      }
    }
  }
}